﻿using System;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace ZHello.Net
{
    public class NetMain
    {
        private const string strx = @"ZeroMQ aims for decentralized intelligence,
but that doesn’t mean your network is empty space in the middle.
It’s filled with message-aware infrastructure and quite often,
we build that infrastructure with ZeroMQ.
The ZeroMQ plumbing can range from tiny pipes to full-blown service-oriented brokers.
The messaging industry calls this intermediation,
meaning that the stuff in the middle deals with either side.
In ZeroMQ, we call these proxies, queues, forwarders, device, or brokers, depending on the context.
symopt // 显示当前所有符号选项
.symopt+ flags // 添加符号选项
.symopt- flags // 删除符号选项
!sym noisy   // 激活详细符号加载(noisy symbol loading)显示
!sym quiet   // 禁止详细符号加载显示
ld * // 为所有模块加载符号
ld kernel32 // 加载kernel32.dll的符号
.reload // 为所有已加载模块载入符号信息
.reload /i // 重新加载不匹配符号的模块【dmp文件没有对应的pdb时使用】
.reload /i TGame.exe // 重新加载不匹配符号的TGame.exe
.reload /f /v // f:强制立即模式（不允许延迟载入）  v:详细模式
.reload /f @""c:\windows\System32\verifier.dll"" // 为指定模块加载符号信息
.reload /f TGame.exe // 为TGame.exe加载符号信息";

        private const string strx2 = @"更";

        public static string GetLocalIP()
        {
            var lis = Dns.GetHostEntry(Dns.GetHostName());
            var ip = lis.AddressList.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork);
            return ip.ToString();
        }

        private static void Client_OnData(object sender, ZHello.MQ.DataArgs e)
        {
            var msg = e.Data;
            var str = msg.Split('\n');
            Console.WriteLine(string.Format("收到:{0}字符，首行:{1}", msg.Length, str[0]));
        }

        private static string Func(string str)
        {
            Console.WriteLine("Recv:" + str);
            return "Ok:" + str;
        }

        private static void InitPubServer()
        {
            var server = MQ.MQFactory.MakePubServer("tcp://127.0.0.1:10088");
            var ip = GetLocalIP();
            server.BindExtraAddress(string.Format("tcp://{0}:10088", ip));
            var msg = new StringBuilder(strx);
            for (int i = 0; i < 500; i++)
            {
                msg.Append(strx);
            }
            while (true)
            {
                Thread.Sleep(100);
                //var time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff");
                string err;
                //msg += time;
                server.Publish(msg.ToString(), out err);
                Console.Title = ("发布端：IP:" + ip + ",Running... " + Environment.TickCount.ToString());
                if (err != null)
                {
                    Console.WriteLine(err);
                }
                else
                    Console.WriteLine("已发送：" + msg.Length + "字符");
            }
        }

        private static void InitRepServer()
        {
            var server = MQ.MQFactory.MakeRepServer("tcp://127.0.0.1:10086");
            server.Respose = Func;
            while (true)
            {
                Console.Title = ("Running... " + Environment.TickCount.ToString());
                System.Threading.Thread.Sleep(500);
            }
        }

        private static void InitSubClient(string serverIP = null)
        {
            var client = MQ.MQFactory.MakeSubClient("tcp://127.0.0.1:10088");
            var ip = serverIP == null ? GetLocalIP() : serverIP;
            client.AddExtraAddress(string.Format("tcp://{0}:10088", ip));
            client.SubcribeAll();
            client.OnData += Client_OnData;
            while (true)
            {
                Thread.Sleep(100);
                Console.Title = ("订阅端监听：IP:" + ip + ",Running... " + Environment.TickCount.ToString());
            }
        }

        private static void Main(string[] args)
        {
            System.Diagnostics.Trace.TraceInformation("调试信息输出");
            try
            {
                Console.WriteLine("客户端或者服务端？c or s or pub:<IP地址>");
                var rk = Console.ReadLine();
                if (rk == "c")
                {
                    InitSubClient();
                }
                else if (rk.StartsWith("pub:"))
                {
                    InitSubClient(rk.Substring(4));
                }
                else
                {
                    InitPubServer();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.WriteLine(ex.Source);
                Console.WriteLine(ex.StackTrace);
            }
            Console.ReadLine();
        }
    }
}